package com.example.sppmode.Common;

import android.content.ContentValues;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;


import com.example.sppmode.DataAccess.MyData;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class PairedDevMgr {
    private static final String TAG = "PairedDevInfo";

    /**
     * hearing detection record table
     */
    public static final String PAIRED_DEV_LIST_TABLE_NAME = "paired_dev_list";
    public static final String PAIRED_DEV_LIST_COL_ID = "id";
    public static final String PAIRED_DEV_LIST_COL_DEV_TYPE = "device_type";
    public static final String PAIRED_DEV_LIST_COL_NAME = "device_name";
    public static final String PAIRED_DEV_LIST_COL_MAC_ADDR = "mac_addr";
    public static final String PAIRED_DEV_LIST_COL_PAIR_TIME = "pair_time";

    public static final int MAX_DEV_CNT = 10;


    public static final String KEY_DEVICE_TYPE = "PairedDevList.KEY_DEVICE_TYPE";
    public static final String KEY_DEVICE_NAME = "PairedDevList.KEY_USER_NAME";
    public static final String KEY_DEVICE_ADDR = "PairedDevList.KEY_DEVICE_ADDR";


    private final List<PairedDeviceInfo> pairedDevList = new ArrayList<>(MAX_DEV_CNT);
    private final PairedDeviceInfo lastConnDevice = new PairedDeviceInfo();

    public PairedDevMgr() {
        createHearingRecordTable();
    }

    public void initData() {
        updateLastConnDevInfo(readDevInfoFromSp(), false);

        pairedDevList.clear();
        new Thread(() -> {
            List<PairedDeviceInfo> pairedDeviceInfoList = getDevListFromDB(1, MAX_DEV_CNT);
            if (pairedDeviceInfoList.size() > 0) {
                pairedDevList.addAll(pairedDeviceInfoList);
            }
        }).start();
    }

    private boolean isClearing = false;

    public boolean clear() {
        if (!isClearing) {
            isClearing = true;

            lastConnDevice.clear();
            saveDevInfoToSp();

            try {
                pairedDevList.clear();
                deleteAllDevFromDB();
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            } finally {
                isClearing = false;
            }
        } else {
            return false;
        }
    }

    public PairedDeviceInfo getLastConnDevice() {
        return lastConnDevice;
    }

    public List<PairedDeviceInfo> getPairedDevList() {
        return pairedDevList;
    }

    public boolean addDevice(PairedDeviceInfo devPaired) {
        if (devPaired == null)
            return false;

        if (devPaired.getName() == null) {
            devPaired.setName("Unknown");
        }
        devPaired.setRssi(0);

        /* 检查设备是否已经存在于列表中，如果存在删除设备 */
        for (PairedDeviceInfo pairedDeviceInfo : pairedDevList) {
            if (pairedDeviceInfo.getMacAddr().equals(devPaired.getMacAddr())) {
                deleteDevFromDBByAddr(pairedDeviceInfo.getMacAddr());
                pairedDevList.remove(pairedDeviceInfo);
                break;
            }
        }

        /* 检查列表是否已经达到最大数，如果是删除最后一个 */
        if (pairedDevList.size() == MAX_DEV_CNT) {
            pairedDevList.remove(pairedDevList.size() - 1);
        }

        /* 添加设备到最前面。按时间排序 */
        devPaired.setPairedTime(System.currentTimeMillis());
        pairedDevList.add(0, devPaired);
        addDevToDB(devPaired);
        return true;
    }

    private List<PairedDeviceInfo> getDeviceList() {
        return pairedDevList;
    }

    /**
     * create paired device list table, _id, device_type, device_name, mac_addr, pair_time
     */
    public void createHearingRecordTable() {
        SQLiteDatabase db = MyData.getInstance().getMyDBHelper().getWritableDatabase();

        String sql = "CREATE TABLE IF NOT EXISTS " + PAIRED_DEV_LIST_TABLE_NAME + "("
                + PAIRED_DEV_LIST_COL_ID + " integer primary key autoincrement, "
                + PAIRED_DEV_LIST_COL_DEV_TYPE + " integer not null, "
                + PAIRED_DEV_LIST_COL_NAME + " varchar(50) not null, "
                + PAIRED_DEV_LIST_COL_MAC_ADDR + " varchar(20) not null, "
                + PAIRED_DEV_LIST_COL_PAIR_TIME + "  long not null)";

        db.execSQL(sql);
    }

    private long addDevToDB(PairedDeviceInfo pairedDeviceInfo) {
        SQLiteDatabase db = MyData.getInstance().getMyDBHelper().getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put(PAIRED_DEV_LIST_COL_DEV_TYPE, pairedDeviceInfo.getDevType());
        contentValues.put(PAIRED_DEV_LIST_COL_NAME, pairedDeviceInfo.getName());
        contentValues.put(PAIRED_DEV_LIST_COL_MAC_ADDR, pairedDeviceInfo.getMacAddr());
        contentValues.put(PAIRED_DEV_LIST_COL_PAIR_TIME, pairedDeviceInfo.getPairedTime());
        return db.insert(PAIRED_DEV_LIST_TABLE_NAME, null, contentValues);
    }

    private int deleteDevFromDBByID(long id) {
        SQLiteDatabase db = MyData.getInstance().getMyDBHelper().getWritableDatabase();

        int ret = db.delete(PAIRED_DEV_LIST_TABLE_NAME, PAIRED_DEV_LIST_COL_ID + "=?", new String[]{id + ""});
        Log.d(TAG, "deletePairedDevFromDB id=" + id + ", ret=" + ret);
        return ret;
    }

    private int deleteDevFromDBByName(String name) {
        SQLiteDatabase db = MyData.getInstance().getMyDBHelper().getWritableDatabase();

        int ret = db.delete(PAIRED_DEV_LIST_TABLE_NAME, PAIRED_DEV_LIST_COL_NAME + "=?", new String[]{name});
        Log.d(TAG, "deletePairedDevFromDB name=" + name + ", ret=" + ret);
        return ret;
    }

    private int deleteDevFromDBByAddr(String macAddr) {
        SQLiteDatabase db = MyData.getInstance().getMyDBHelper().getWritableDatabase();

        int ret = db.delete(PAIRED_DEV_LIST_TABLE_NAME, PAIRED_DEV_LIST_COL_MAC_ADDR + "=?", new String[]{macAddr});
        Log.d(TAG, "deletePairedDevFromDB name=" + macAddr + ", ret=" + ret);
        return ret;
    }

    private int deleteAllDevFromDB() {
        SQLiteDatabase db = MyData.getInstance().getMyDBHelper().getWritableDatabase();
        String sql = "delete from " + PAIRED_DEV_LIST_TABLE_NAME;
        Log.d(TAG, "deletePairedDevFromDB sql=" + sql);

        db.execSQL(sql);
        return 0;
    }

    private List<PairedDeviceInfo> getDevListFromDB(int start, int end) {
        SQLiteDatabase db = MyData.getInstance().getMyDBHelper().getWritableDatabase();
        List<PairedDeviceInfo> pairedDeviceInfoList = new LinkedList<>();

        /*
         * 参数1：表名
         * 参数2：columns, 要查出来的列名。
         * 参数3：selection， 查询条件
         * 参数4：selectionArgs，对应selection参数
         * 参数5：groupby
         * 参数6：having
         * 参数7：orderBy， 排序
         */
        Cursor cursor = db.query(PAIRED_DEV_LIST_TABLE_NAME, null, null, null, null, null, null);
        int index = start;
        cursor.move(index);

        while (!cursor.isAfterLast()) {
            PairedDeviceInfo pairedDeviceInfo = new PairedDeviceInfo();
            //deviceInfo.setId(cursor.getInt(0));
            pairedDeviceInfo.setDevType(cursor.getInt(1));
            pairedDeviceInfo.setName(cursor.getString(2));
            pairedDeviceInfo.setMacAddr(cursor.getString(3));
            pairedDeviceInfo.setPairedTime(cursor.getLong(4));
            pairedDeviceInfoList.add(pairedDeviceInfo);

            if (index >= end) {
                break;
            } else {
                index++;
                cursor.moveToNext();
            }
        }
        cursor.close();
        return pairedDeviceInfoList;
    }


    public void updateLastConnDevInfo(PairedDeviceInfo pairedDeviceInfo, boolean save) {
        lastConnDevice.setName(pairedDeviceInfo.getName());
        lastConnDevice.setMacAddr(pairedDeviceInfo.getMacAddr());
        lastConnDevice.setDevType(pairedDeviceInfo.getDevType());

        if (save)
            saveDevInfoToSp();
    }

    public boolean saveDevInfoToSp() {
        SharedPreferences sp = MyData.getInstance().getMySP();
        SharedPreferences.Editor editor = sp.edit();
        editor.putInt(KEY_DEVICE_TYPE, lastConnDevice.getDevType());
        editor.putString(KEY_DEVICE_NAME, lastConnDevice.getName());
        editor.putString(KEY_DEVICE_ADDR, lastConnDevice.getMacAddr());
        editor.apply();
        return true;
    }

    public PairedDeviceInfo readDevInfoFromSp() {
        SharedPreferences sp = MyData.getInstance().getMySP();
        PairedDeviceInfo pairedDeviceInfo = new PairedDeviceInfo();
        pairedDeviceInfo.setDevType(sp.getInt(KEY_DEVICE_TYPE, PairedDeviceInfo.DEVICE_TYPE_COMMON));
        pairedDeviceInfo.setName(sp.getString(KEY_DEVICE_NAME, null));
        pairedDeviceInfo.setMacAddr(sp.getString(KEY_DEVICE_ADDR, PairedDeviceInfo.DEFAULT_MAC_ADDR));

        return pairedDeviceInfo;
    }
}
